<?php

/** 
 *  Library Boleto for codeigniter
 *
 *
 *  @package Bibliotecas
 *  @category Utils
 *  @author Carlos O Carvalho
 *  @version 1.0.0
 *  @access public
 */




require_once APPPATH.'libraries/IBoleto.php';
require_once APPPATH.'libraries/Boletos_Layout.php';

class Boleto_Bradesco implements Iboleto{
     
     var $url_folder_images = '/public/images/boletos/';
     private $config = array(
        'show_print'=>false,
        'name_cliente'=>'',
        'name_loja'=>'',
        'razao_name'=>'',
        'cidade_uf'=>'',
        'cidade_cliente'=>'',
        'uf_cliente'=>'',
        'logradouro_cliente'=>'',
        'logradouro_empresa'=>'',
        'agencia'=>0001,
        'agencia_digito'=>0,
        'conta'=>'100000',
        'conta_digito'=>8,
        'carteira'=>'09',
        'data_documento'=>'',
        'taxa'=>00.00,
        'prazo'=>3,
        'cpf_cnpj'=>'',
        'demonstrativo1'=>'',
        'demonstrativo2'=>'',
        'demonstrativo3'=>'',
        'conta_cedente'=>'00000',
        'conta_cedente_dv'=>0,
        'cep_cliente'=>'00000-000',
        'price'=>00.00,
         'instrucoes1'=>'Sr. Caixa, cobrar multa de 2% após o vencimento',
         'instrucoes2'=>'Receber até 10 dias após o vencimento',
         'instrucoes3'=>'Em caso de dúvidas entre em contato conosco: xxxx@xxxx.com.br',
         'instrucoes4'=>'Emitido pelo sistema online',
        'nosso_numero'=>'0000000' //max 11 digits 
        );

    function __construct(){
      $this->layout = new Boletos_Layout();
    }


    function digitoVerificador_nossonumero($numero) {
	$resto2 = $this->modulo_11($numero, 7, 1);
     $digito = 11 - $resto2;
     if ($digito == 10) {
        $dv = "P";
     } elseif($digito == 11) {
     	$dv = 0;
	} else {
        $dv = $digito;
     	}
	 return $dv;
}


function digitoVerificador_barra($numero) {
	$resto2 = $this->modulo_11($numero, 9, 1);
     if ($resto2 == 0 || $resto2 == 1 || $resto2 == 10) {
        $dv = 1;
     } else {
	 	$dv = 11 - $resto2;
     }
	 return $dv;
}


// FUNÇÕES
// Algumas foram retiradas do Projeto PhpBoleto e modificadas para atender as particularidades de cada banco

function formata_numero($numero,$loop,$insert,$tipo = "geral") {
	if ($tipo == "geral") {
		$numero = str_replace(",","",$numero);
		while(strlen($numero)<$loop){
			$numero = $insert . $numero;
		}
	}
	if ($tipo == "valor") {
		/*
		retira as virgulas
		formata o numero
		preenche com zeros
		*/
		$numero = str_replace(",","",$numero);
		while(strlen($numero)<$loop){
			$numero = $insert . $numero;
		}
	}
	if ($tipo == "convenio") {
		while(strlen($numero)<$loop){
			$numero = $numero . $insert;
		}
	}
	return $numero;
}


function fbarcode($valor){

$fino = 1 ;
$largo = 3 ;
$altura = 50 ;

  $barcodes[0] = "00110" ;
  $barcodes[1] = "10001" ;
  $barcodes[2] = "01001" ;
  $barcodes[3] = "11000" ;
  $barcodes[4] = "00101" ;
  $barcodes[5] = "10100" ;
  $barcodes[6] = "01100" ;
  $barcodes[7] = "00011" ;
  $barcodes[8] = "10010" ;
  $barcodes[9] = "01010" ;
  for($f1=9;$f1>=0;$f1--){ 
    for($f2=9;$f2>=0;$f2--){  
      $f = ($f1 * 10) + $f2 ;
      $texto = "" ;
      for($i=1;$i<6;$i++){ 
        $texto .=  substr($barcodes[$f1],($i-1),1) . substr($barcodes[$f2],($i-1),1);
      }
      $barcodes[$f] = $texto;
    }
  }


//Desenho da barra


//Guarda inicial
  ob_start();
?>

<img src=<?php echo $this->url_folder_images ?>p.png width=<?php echo $fino?> height=<?php echo $altura?> border=0><img 
src=<?php echo $this->url_folder_images ?>b.png width=<?php echo $fino?> height=<?php echo $altura?> border=0><img 
src=<?php echo $this->url_folder_images ?>p.png width=<?php echo $fino?> height=<?php echo $altura?> border=0><img 
src=<?php echo $this->url_folder_images ?>b.png width=<?php echo $fino?> height=<?php echo $altura?> border=0><img 
<?php
$texto = $valor ;
if((strlen($texto) % 2) <> 0){
	$texto = "0" . $texto;
}

// Draw dos dados
while (strlen($texto) > 0) {
  $i = round($this->esquerda($texto,2));
  $texto = $this->direita($texto,strlen($texto)-2);
  $f = $barcodes[$i];
  for($i=1;$i<11;$i+=2){
    if (substr($f,($i-1),1) == "0") {
      $f1 = $fino ;
    }else{
      $f1 = $largo ;
    }
?>
    src=<?php echo $this->url_folder_images ?>p.png width=<?php echo $f1?> height=<?php echo $altura?> border=0><img 
<?php
    if (substr($f,$i,1) == "0") {
      $f2 = $fino ;
    }else{
      $f2 = $largo ;
    }
?>
    src=<?php echo $this->url_folder_images ?>b.png width=<?php echo $f2?> height=<?php echo $altura?> border=0><img 
<?php
  }
}

// Draw guarda final
?>
src=<?php echo $this->url_folder_images ?>p.png width=<?php echo $largo?> height=<?php echo $altura?> border=0><img 
src=<?php echo $this->url_folder_images ?>b.png width=<?php echo $fino?> height=<?php echo $altura?> border=0><img 
src=<?php echo $this->url_folder_images ?>p.png width=<?php echo 1?> height=<?php echo $altura?> border=0> 
  <?php
  return ob_get_clean();
} //Fim da função

function esquerda($entra,$comp){
	return substr($entra,0,$comp);
}

function direita($entra,$comp){
	return substr($entra,strlen($entra)-$comp,$comp);
}

function fator_vencimento($data) {
	$data = explode("/",$data);
	$ano = $data[2];
	$mes = $data[1];
	$dia = $data[0];
    return(abs(($this->_dateToDays("1997","10","07")) - ($this->_dateToDays($ano, $mes, $dia))));
}

function _dateToDays($year,$month,$day) {
    $century = substr($year, 0, 2);
    $year = substr($year, 2, 2);
    if ($month > 2) {
        $month -= 3;
    } else {
        $month += 9;
        if ($year) {
            $year--;
        } else {
            $year = 99;
            $century --;
        }
    }
    return ( floor((  146097 * $century)    /  4 ) +
            floor(( 1461 * $year)        /  4 ) +
            floor(( 153 * $month +  2) /  5 ) +
                $day +  1721119);
}

function modulo_10($num) { 
		$numtotal10 = 0;
        $fator = 2;

        // Separacao dos numeros
        for ($i = strlen($num); $i > 0; $i--) {
            // pega cada numero isoladamente
            $numeros[$i] = substr($num,$i-1,1);
            // Efetua multiplicacao do numero pelo (falor 10)
            // 2002-07-07 01:33:34 Macete para adequar ao Mod10 do Itaú
            $temp = $numeros[$i] * $fator; 
            $temp0=0;
            foreach (preg_split('//',$temp,-1,PREG_SPLIT_NO_EMPTY) as $k=>$v){ $temp0+=$v; }
            $parcial10[$i] = $temp0; //$numeros[$i] * $fator;
            // monta sequencia para soma dos digitos no (modulo 10)
            $numtotal10 += $parcial10[$i];
            if ($fator == 2) {
                $fator = 1;
            } else {
                $fator = 2; // intercala fator de multiplicacao (modulo 10)
            }
        }
		
        // várias linhas removidas, vide função original
        // Calculo do modulo 10
        $resto = $numtotal10 % 10;
        $digito = 10 - $resto;
        if ($resto == 0) {
            $digito = 0;
        }
		
        return $digito;
		
}

function modulo_11($num, $base=9, $r=0)  {
    /**
     *   Autor:
     *           Pablo Costa <pablo@users.sourceforge.net>
     *
     *   Função:
     *    Calculo do Modulo 11 para geracao do digito verificador 
     *    de boletos bancarios conforme documentos obtidos 
     *    da Febraban - www.febraban.org.br 
     *
     *   Entrada:
     *     $num: string numérica para a qual se deseja calcularo digito verificador;
     *     $base: valor maximo de multiplicacao [2-$base]
     *     $r: quando especificado um devolve somente o resto
     *
     *   Saída:
     *     Retorna o Digito verificador.
     *
     *   Observações:
     *     - Script desenvolvido sem nenhum reaproveitamento de código pré existente.
     *     - Assume-se que a verificação do formato das variáveis de entrada é feita antes da execução deste script.
     */                                        

    $soma = 0;
    $fator = 2;

    /* Separacao dos numeros */
    for ($i = strlen($num); $i > 0; $i--) {
        // pega cada numero isoladamente
        $numeros[$i] = substr($num,$i-1,1);
        // Efetua multiplicacao do numero pelo falor
        $parcial[$i] = $numeros[$i] * $fator;
        // Soma dos digitos
        $soma += $parcial[$i];
        if ($fator == $base) {
            // restaura fator de multiplicacao para 2 
            $fator = 1;
        }
        $fator++;
    }

    /* Calculo do modulo 11 */
    if ($r == 0) {
        $soma *= 10;
        $digito = $soma % 11;
        if ($digito == 10) {
            $digito = 0;
        }
        return $digito;
    } elseif ($r == 1){
        $resto = $soma % 11;
        return $resto;
    }
}

function monta_linha_digitavel($codigo) {

	// 01-03    -> Código do banco sem o digito
	// 04-04    -> Código da Moeda (9-Real)
	// 05-05    -> Dígito verificador do código de barras
	// 06-09    -> Fator de vencimento
	// 10-19    -> Valor Nominal do Título
	// 20-44    -> Campo Livre (Abaixo)
	
	// 20-23    -> Código da Agencia (sem dígito)
	// 24-05    -> Número da Carteira
	// 26-36    -> Nosso Número (sem dígito)
	// 37-43    -> Conta do Cedente (sem dígito)
	// 44-44    -> Zero (Fixo)
        

        // 1. Campo - composto pelo código do banco, código da moéda, as cinco primeiras posições
        // do campo livre e DV (modulo10) deste campo
        
        $p1 = substr($codigo, 0, 4);							// Numero do banco + Carteira
        $p2 = substr($codigo, 19, 5);						// 5 primeiras posições do campo livre
        $p3 = $this->modulo_10("$p1$p2");						// Digito do campo 1
        $p4 = "$p1$p2$p3";								// União
        $campo1 = substr($p4, 0, 5).'.'.substr($p4, 5);

        // 2. Campo - composto pelas posiçoes 6 a 15 do campo livre
        // e livre e DV (modulo10) deste campo
        $p1 = substr($codigo, 24, 10);						//Posições de 6 a 15 do campo livre
        $p2 = $this->modulo_10($p1);								//Digito do campo 2	
        $p3 = "$p1$p2";
        $campo2 = substr($p3, 0, 5).'.'.substr($p3, 5);

        // 3. Campo composto pelas posicoes 16 a 25 do campo livre
        // e livre e DV (modulo10) deste campo
        $p1 = substr($codigo, 34, 10);						//Posições de 16 a 25 do campo livre
        $p2 = $this->modulo_10($p1);								//Digito do Campo 3
        $p3 = "$p1$p2";
        $campo3 = substr($p3, 0, 5).'.'.substr($p3, 5);

        // 4. Campo - digito verificador do codigo de barras
        $campo4 = substr($codigo, 4, 1);

        // 5. Campo composto pelo fator vencimento e valor nominal do documento, sem
        // indicacao de zeros a esquerda e sem edicao (sem ponto e virgula). Quando se
        // tratar de valor zerado, a representacao deve ser 000 (tres zeros).
		$p1 = substr($codigo, 5, 4);
		$p2 = substr($codigo, 9, 10);
		$campo5 = "$p1$p2";

        return "$campo1 $campo2 $campo3 $campo4 $campo5"; 
}

function geraCodigoBanco($numero) {
    $parte1 = substr($numero, 0, 3);
    $parte2 = $this->modulo_11($parte1);
    return $parte1 . "-" . $parte2;
}




	function generate($config){
              
              $this->config = array_merge($this->config,$config);
             $dias_de_prazo_para_pagamento = $this->config['prazo'];
             $taxa_boleto = $this->config['taxa'];
                $data_venc = date("d/m/Y", time() + ($dias_de_prazo_para_pagamento * 86400));  // Prazo de X dias OU informe data: "13/04/2006"; 
                $valor_cobrado = $this->config['price']; // Valor - REGRA: Sem pontos na milhar e tanto faz com "." ou "," ou com 1 ou 2 ou sem casa decimal
                $valor_cobrado = str_replace(",", ".",$valor_cobrado);
                $valor_boleto=number_format($valor_cobrado+$taxa_boleto, 2, ',', '');

                $dadosboleto["nosso_numero"] = $this->config['nosso_numero'];  // Nosso numero sem o DV - REGRA: Máximo de 11 caracteres!
                $dadosboleto["numero_documento"] = $dadosboleto["nosso_numero"];  // Num do pedido ou do documento = Nosso numero
                $dadosboleto["data_vencimento"] = $data_venc; // Data de Vencimento do Boleto - REGRA: Formato DD/MM/AAAA
                $dadosboleto["data_documento"] = $this->config['data_documento']; // Data de emissão do Boleto
                $dadosboleto["data_processamento"] = $this->config['data_documento']; // Data de processamento do boleto (opcional)
                $dadosboleto["valor_boleto"] = $valor_boleto;   // Valor do Boleto - REGRA: Com vírgula e sempre com duas casas depois da virgula

                // DADOS DO SEU CLIENTE
                $dadosboleto["sacado"] = $this->config['name_cliente'];
                $dadosboleto["endereco1"] = $this->config['logradouro_cliente'];
                $dadosboleto["endereco2"] = $this->config['cidade_cliente'].' / '.$this->config['uf_cliente'].' '.$this->config['cep_cliente'] ;

                // INFORMACOES PARA O CLIENTE
                $dadosboleto["demonstrativo1"] = $this->config['name_loja'];
                $dadosboleto["demonstrativo2"] = $this->config['demonstrativo2'];
                $dadosboleto["demonstrativo3"] = " ".$this->config['demonstrativo3'];
                $dadosboleto["instrucoes1"] = "- ".$this->config['instrucoes1'];
                $dadosboleto["instrucoes2"] = "- ".$this->config['instrucoes2'];
                $dadosboleto["instrucoes3"] = "- ".$this->config['instrucoes3'];
                $dadosboleto["instrucoes4"] = "&nbsp; ".$this->config['instrucoes4'];

                // DADOS OPCIONAIS DE ACORDO COM O BANCO OU CLIENTE
                $dadosboleto["quantidade"] = "001";
                $dadosboleto["valor_unitario"] = $valor_boleto;
                $dadosboleto["aceite"] = "";    
                $dadosboleto["especie"] = "R$";
                $dadosboleto["especie_doc"] = "DS";


                // ---------------------- DADOS FIXOS DE CONFIGURAÇÃO DO SEU BOLETO --------------- //


                // DADOS DA SUA CONTA - Bradesco
                $dadosboleto["agencia"] = $this->config['agencia']; // Num da agencia, sem digito
                $dadosboleto["agencia_dv"] = $this->config['agencia_digito']; // Digito do Num da agencia
                $dadosboleto["conta"] = $this->config['conta'];  // Num da conta, sem digito
                $dadosboleto["conta_dv"] = $this->config['conta_digito'];   // Digito do Num da conta

                // DADOS PERSONALIZADOS - Bradesco
                $dadosboleto["conta_cedente"] = $this->config['conta']; // ContaCedente do Cliente, sem digito (Somente Números)
                $dadosboleto["conta_cedente_dv"] = $this->config['conta_digito']; // Digito da ContaCedente do Cliente
                $dadosboleto["carteira"] = $this->config['carteira'];  // Código da Carteira: pode ser 06 ou 03

                // SEUS DADOS
                $dadosboleto["identificacao"] = base_url()." Boleto gerado online " . date('dmYHis') ;
                $dadosboleto["cpf_cnpj"] = $this->config['cpf_cnpj'];
                $dadosboleto["endereco"] = $this->config['logradouro_empresa'];
                $dadosboleto["cidade_uf"] = $this->config['cidade_uf'];
                $dadosboleto["cedente"] = $this->config['razao_name'];

                //generate 
                $codigobanco = "237";
                $codigo_banco_com_dv = $this->geraCodigoBanco($codigobanco);
                $nummoeda = "9";
                $fator_vencimento = $this->fator_vencimento($dadosboleto["data_vencimento"]);

                //valor tem 10 digitos, sem virgula
                $valor = $this->formata_numero($dadosboleto["valor_boleto"],10,0,"valor");
                //agencia é 4 digitos
                $agencia = $this->formata_numero($dadosboleto["agencia"],4,0);
                //conta é 6 digitos
                $conta = $this->formata_numero($dadosboleto["conta"],6,0);
                //dv da conta
                $conta_dv = $this->formata_numero($dadosboleto["conta_dv"],1,0);
                //carteira é 2 caracteres
                $carteira = $dadosboleto["carteira"];

                //nosso número (sem dv) é 11 digitos
                $nnum = $this->formata_numero($dadosboleto["carteira"],2,0).$this->formata_numero($dadosboleto["nosso_numero"],11,0);
                //dv do nosso número
                $dv_nosso_numero = $this->digitoVerificador_nossonumero($nnum);

                //conta cedente (sem dv) é 7 digitos
                $conta_cedente = $this->formata_numero($dadosboleto["conta_cedente"],7,0);
                //dv da conta cedente
                $conta_cedente_dv = $this->formata_numero($dadosboleto["conta_cedente_dv"],1,0);

                //$ag_contacedente = $agencia . $conta_cedente;

                // 43 numeros para o calculo do digito verificador do codigo de barras
                $dv = $this->digitoVerificador_barra("$codigobanco$nummoeda$fator_vencimento$valor$agencia$nnum$conta_cedente".'0', 9, 0);
                // Numero para o codigo de barras com 44 digitos
                $linha = "$codigobanco$nummoeda$dv$fator_vencimento$valor$agencia$nnum$conta_cedente"."0";

                $nossonumero = substr($nnum,0,2).'/'.substr($nnum,2).'-'.$dv_nosso_numero;
                $agencia_codigo = $agencia."-".$dadosboleto["agencia_dv"]." / ". $conta_cedente ."-". $conta_cedente_dv;


       $dadosboleto["codigo_barras"] = $linha;
       $dadosboleto["linha_digitavel"] = $this->monta_linha_digitavel($linha);
       $dadosboleto["agencia_codigo"] = $agencia_codigo;
       $dadosboleto["nosso_numero"] = $nossonumero;
       $dadosboleto["codigo_banco_com_dv"] = $codigo_banco_com_dv;
       $dadosboleto['bar_code_image'] = $this->fbarcode($linha);
        
     echo $this->layout->bradesco($dadosboleto,$this->config['show_print']);
	}

}